#include <string.h>
#include <stdio.h>
#include "mhscpu.h"

void clearBPK(void);
void setBPK(void);
void printBPK(void);

void NVIC_Configuration(void);
void UART_Configuration(void);
void SysTick_Configuration(void);
void TIMER_Configuration(void);
void SENSOR_Configuration(void);
void SYSTEM_Init(void);

void SENSOR_Cmd(void);


int main(void)
{
// 	SYSCTRL_PLLConfig(SYSCTRL_PLL_96MHz);
// 	SYSCTRL_HCLKConfig(SYSCTRL_HCLK_Div_None);
// 	SYSCTRL_PCLKConfig(SYSCTRL_PCLK_Div2);
	
	SYSTEM_Init();
	
	printf("MegaHunt SCPU SENSOR Test V1.0.\r\n");
	
	SENSOR_Cmd();

	while(1)
	{

	}

}

void SYSTEM_Init(void)
{	
	SYSCTRL_APBPeriphClockCmd(SYSCTRL_APBPeriph_UART0 | SYSCTRL_APBPeriph_BPU | SYSCTRL_APBPeriph_GPIO,ENABLE);
	SYSCTRL_APBPeriphResetCmd(SYSCTRL_APBPeriph_UART0 | SYSCTRL_APBPeriph_BPU,ENABLE);
	
	SENSOR_EXTCmd(DISABLE);
	SENSOR_EXTPortCmd(SENSOR_Port_All, DISABLE);
	SENSOR_ANACmd(SENSOR_ANA_MESH, DISABLE);
	SENSOR_ClearITPendingBit();
	
	UART_Configuration();
	NVIC_Configuration();
	TIMER_Configuration();
	
	{
		uint32_t i = 0x1FFF;
		while(i--);
	}
}

const char *menu[50] = {
	"0.EXT Port All Pull Up\n",
	"1.EXT Port All Static High Effect\n",
	"2.EXT Port All Static Low Effect\n",
	"3.EXT Port All Dynamic\n",
	"4.EXT Port Dynamic and Static\n",
	"5.ANA All\n",
	"6.ANA Only VOL HIGH\n",
	"7.ANA Only VOL LOW\n",
	"8.ANA Only TEMPER HIGH\n",
	"9.ANA Only TEMPER LOW\n",
	"a.ANA Only MESH\n",
	"b.ANA Only VOL GLITCH\n",
	"c.ANA Only XTAL32K\n",
	"d.SENSOR Response Interrupt\n",
	"e.SENSOR Response Core Reset\n",
	"f.SENSOR DynamicFre 31_25ms\n",
	"g.SENSOR DynamicFre 125ms\n",
	"h.SENSOR DynamicFre 500ms\n",
	"i.SENSOR DynamicFre 1s\n",
	"j.Delay By Pass\n",
	"k.clear bpk data\n"
	"l.set bpk data\n"
	"m.print bpk data\n"
	"n.systick enable\n"
	"o.timer enable\n"
	"p.timer disable\n"
	"s.SYSCLOCK 96m\n"
	"t.SYSCLOCK 72m\n"
	"x.Printf Select\n",
	"y.SENSOR Enable\n",
	"z.print Menu\n",
	NULL
};

void printPara(void);
void printMenu(void);
uint8_t GetCmd(void);


typedef struct 
{
	uint32_t PortPullUp;
	uint32_t EXT;
	uint32_t ANA;
	uint32_t SensorResponse;
	uint32_t DynamicFre;
	uint32_t ByPass;
}SENSOR_ParaTypeDef;

SENSOR_ParaTypeDef para;

void SENSOR_Cmd(void)
{
	volatile uint8_t tmpCmd = 0;
	memset(&para, 0, sizeof(para));
	printMenu();
	while(TRUE)
	{
		tmpCmd = GetCmd();
		if (tmpCmd)
		{
			switch(tmpCmd)
			{
			case '0':
				{
					if (para.PortPullUp)
					{
						para.PortPullUp = 0;
					} 
					else
					{
						para.PortPullUp = 1;
					}
					break;
				}
			case '1':
			case '2':
			case '3':
			case '4':
				{
					if (para.EXT == (tmpCmd - 0x30))
					{
						para.EXT = 0;
					} 
					else
					{
						para.EXT = (tmpCmd - 0x30);
					}
					break;
				}
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				{
					if (para.ANA == (tmpCmd - 0x30))
					{
						para.ANA = 0;
					} 
					else
					{
						para.ANA = (tmpCmd - 0x30);
					}
					break;
				}
			case 'a':
				{
					if (para.ANA == 10)
					{
						para.ANA = 0;
					} 
					else
					{
						para.ANA = 10;
					}
					break;
				}
			case 'b':
				{
					if (para.ANA == 11)
					{
						para.ANA = 0;
					} 
					else
					{
						para.ANA = 11;
					}
					break;
				}
			case 'c':
				{
					if (para.ANA == 12)
					{
						para.ANA = 0;
					} 
					else
					{
						para.ANA = 12;
					}
					break;
				}
			case 'd':
				{
					para.SensorResponse = 0;
					break;
				}
			case 'e':
				{
					para.SensorResponse = 1;
					break;
				}
			case 'f':
				{
					para.DynamicFre = SENSOR_DynamicFrequency_31_25ms;
					break;
				}
			case 'g':
				{
					para.DynamicFre = SENSOR_DynamicFrequency_125ms;
					break;
				}
			case 'h':
				{
					para.DynamicFre = SENSOR_DynamicFrequency_500ms;
					break;
				}
			case 'i':
				{
					para.DynamicFre = SENSOR_DynamicFrequency_1s;
					break;
				}
			case 'j':
				{
					if (para.ByPass == (tmpCmd - 0x30))
					{
						para.ByPass = 0;
					} 
					else
					{
						para.ByPass = (tmpCmd - 0x30);
					}
					break;
				}
			case 'k':
				{
					clearBPK();
					break;
				}
			case 'l':
				{
					setBPK();
					break;
				}
			case 'm':
				{
					printBPK();
					break;
				}
			case 'n':
				{
					SysTick_Configuration();
					break;
				}
			case 'o':
				{
					TIM_Cmd(TIMM0, TIM_0,ENABLE);
					break;
				}
			case 'p':
				{
					TIM_Cmd(TIMM0, TIM_0,DISABLE);
					break;
				}
			case 's':
				{
					SYSCTRL_PLLConfig(SYSCTRL_PLL_96MHz);
					SYSCTRL_HCLKConfig(SYSCTRL_HCLK_Div_None);
					SYSCTRL_PCLKConfig(SYSCTRL_PCLK_Div2);
					
					SYSTEM_Init();
					printMenu();
					break;
				}
			case 't':
				{
					SYSCTRL_PLLConfig(SYSCTRL_PLL_72MHz);
					SYSCTRL_HCLKConfig(SYSCTRL_HCLK_Div_None);
					SYSCTRL_PCLKConfig(SYSCTRL_PCLK_Div2);
					
					SYSTEM_Init();
					printMenu();
					break;
				}
			case 'x':
				{
					printPara();
					break;
				}
			case 'y':
				{
					SENSOR_Configuration();
					break;
				}
			case 'z':
			default:
				{
					printMenu();
					break;
				}
			}
		}
	}
}

void printMenu(void)
{
	uint32_t i;
	SYSCTRL_ClocksTypeDef clocks;
	
	SYSCTRL_GetClocksFreq(&clocks);
	
	printf("\n================%d Sensor Test Menu===============\n", clocks.PLL_Frequency / 1000000);
	for (i = 0; menu[i] != NULL; i++)
	{
		printf("%s", menu[i]);
	}
	printf("====================Menu End=================\n");
}

void printPara(void)
{
	if (para.PortPullUp)
		printf("%s", menu[0]);

	if (para.EXT != 0)
		printf("%s", menu[para.EXT]);
	if (para.ANA != 0)
		printf("%s", menu[para.ANA]);
	
	switch(para.DynamicFre)
	{
		case SENSOR_DynamicFrequency_31_25ms:
		{
			printf("%s", menu[15]);
			break;
		}
		case SENSOR_DynamicFrequency_125ms:
		{
			printf("%s", menu[16]);
			break;
		}
		case SENSOR_DynamicFrequency_500ms:
		{
			printf("%s", menu[17]);
			break;
		}
		case SENSOR_DynamicFrequency_1s:
		{
			printf("%s", menu[18]);
			break;
		}
		
	}
	
	if	(para.ByPass != 0)
		printf("%s", menu[19]);
	
	if (para.SensorResponse == 0)
		printf("%s", menu[13]);
	if (para.SensorResponse == 1)
		printf("%s", menu[14]);
}

uint8_t GetCmd(void)
{
	uint8_t tmp = 0;

	if(UART_GetLineStatus(UART0) & UART_LINE_STATUS_RX_RECVD)
	{
		tmp = UART_ReceiveData(UART0);
	}
	if(tmp)
	{
		printf("cmd is %c\n", tmp);
	}

	return tmp;
}

void SENSOR_Configuration(void)
{
	
	SENSOR_EXTInitTypeDef SNESOR_EXTInitStruct;
	uint32_t SENSOR_ANA;
	memset(&SNESOR_EXTInitStruct, 0, sizeof(SNESOR_EXTInitStruct));

	if (para.PortPullUp)
	{
		SNESOR_EXTInitStruct.SENSOR_Port_PullUp =	SENSOR_Port_S0| SENSOR_Port_S1|
													SENSOR_Port_S2| SENSOR_Port_S3|
													SENSOR_Port_S4| SENSOR_Port_S5;
	} 
	else
	{
		SNESOR_EXTInitStruct.SENSOR_Port_PullUp = 0;
	}

	switch(para.EXT)
	{
	case 0:
		{
			SNESOR_EXTInitStruct.SENSOR_Port_StaticLowEffect = 0;
			SNESOR_EXTInitStruct.SENSOR_Port_StaticHighEffect = 0;
			break;
		}
	case 1:
		{
			SNESOR_EXTInitStruct.SENSOR_Port_StaticHighEffect = SENSOR_Port_S0| SENSOR_Port_S1|
																SENSOR_Port_S2| SENSOR_Port_S3|
																SENSOR_Port_S4| SENSOR_Port_S5;
			break;
		}
	case 2:
		{
			SNESOR_EXTInitStruct.SENSOR_Port_StaticLowEffect = SENSOR_Port_S0| SENSOR_Port_S1|
																SENSOR_Port_S2| SENSOR_Port_S3|
																SENSOR_Port_S4| SENSOR_Port_S5;
			break;
		}
	case 3:
		{
			SNESOR_EXTInitStruct.SENSOR_Port_Dynamic = 			SENSOR_Port_S0| SENSOR_Port_S1|
																SENSOR_Port_S2| SENSOR_Port_S3|
																SENSOR_Port_S4| SENSOR_Port_S5;
			break;
		}
	case 4:
		{
			
			SNESOR_EXTInitStruct.SENSOR_Port_StaticLowEffect =  SENSOR_Port_S0| SENSOR_Port_S1;
			SNESOR_EXTInitStruct.SENSOR_Port_StaticHighEffect =	SENSOR_Port_S2| SENSOR_Port_S3;
			
			SNESOR_EXTInitStruct.SENSOR_Port_Dynamic =  		SENSOR_Port_S4| SENSOR_Port_S5;
			
// 			SNESOR_EXTInitStruct.SENSOR_Port_PullUp =	SENSOR_Port_S0| SENSOR_Port_S1;
			break;
		}
	}

	switch(para.ANA)
	{
	case 6:
		{
			SENSOR_ANA = SENSOR_ANA_VOL_HIGH;
			break;
		}
	case 7:
		{
			SENSOR_ANA = SENSOR_ANA_VOL_LOW;
			break;
		}
	case 8:
		{
			SENSOR_ANA = SENSOR_ANA_TEMPER_HIGH;
			break;
		}
	case 9:
		{
			SENSOR_ANA = SENSOR_ANA_TEMPER_LOW;
			break;
		}
	case 0xa:
		{
			SENSOR_ANA = SENSOR_ANA_MESH;
			break;
		}
	case 0xb:
		{
			SENSOR_ANA = SENSOR_ANA_VOLGLITCH;
			break;
		}
	case 0xc:
		{
			SENSOR_ANA = SENSOR_ANA_XTAL32K;
			break;
		}
	case 5:
		{
			SENSOR_ANA = SENSOR_ANA_VOL_HIGH|
				SENSOR_ANA_VOL_LOW|
				SENSOR_ANA_TEMPER_HIGH|
				SENSOR_ANA_TEMPER_LOW|
				SENSOR_ANA_MESH |
				SENSOR_ANA_XTAL32K|
				SENSOR_ANA_VOLGLITCH;
			break;
		}
	}

	if (para.SensorResponse == 0)
	{
		SENSOR_AttackRespMode(SENSOR_Interrupt);
	} 
	else
	{
		SENSOR_AttackRespMode(SENSOR_CPUReset);
	}

	SNESOR_EXTInitStruct.SENSOR_DynamicFrequency = para.DynamicFre;
	

	if(para.ByPass)
	{
		SENSOR->SEN_VG_DETECT |= 0X04;
	}
	else
	{
		SENSOR->SEN_VG_DETECT &= ~0X04;
	}
	
	SNESOR_EXTInitStruct.SENSOR_Port_Enable = ENABLE;
	SENSOR_EXTInit(&SNESOR_EXTInitStruct);
	
	SENSOR_EXTCmd(ENABLE);
	if (para.ANA)
	{
		SENSOR_ANACmd(SENSOR_ANA, ENABLE);
	}
}


void clearBPK(void)
{
	uint32_t buf[32];
	uint32_t index = 0;
	
	while(BPK_IsReady() == RESET);
	
	//clear buf
	memset(buf, 0, sizeof(buf));

	printf("bufValue:\n");
	for(index = 0;index < sizeof(buf)/sizeof(buf[0]);index++)
	{
		printf("%08X ", buf[index]);
		if (3 == index % 4)
		{
			printf("\n");
		}
	}
	printf("\n");
	BPK_WriteKey(buf,sizeof(buf)/sizeof(buf[0]),0);
}

void setBPK(void)
{
	uint32_t buf[32];
	uint32_t index = 0;
	
	while(BPK_IsReady() == RESET);
	
	//set buf 0~X
	for(index = 0;index < sizeof(buf)/sizeof(buf[0]);index++)
	{
		buf[index] = index;
	}

	printf("bufValue:\n");
	for(index = 0;index < sizeof(buf)/sizeof(buf[0]);index++)
	{
		printf("%08X ", buf[index]);
		if (3 == index % 4)
		{
			printf("\n");
		}
	}
	printf("\n");
	BPK_WriteKey(buf,sizeof(buf)/sizeof(buf[0]),0);
}

void printBPK(void)
{
	uint32_t key[32];
	uint32_t index = 0;
	
	while(BPK_IsReady() == RESET);

	printf("readKey:\n");
	memset(key, 0, sizeof(key));
	BPK_ReadKey(key,sizeof(key)/sizeof(key[0]),0);
	for(index = 0;index < sizeof(key)/sizeof(key[0]);index++)
	{
		printf("%08X ", key[index]);
		if (3 == index % 4)
		{
			printf("\n");
		}
	}
	printf("\n");
	memset(key, 0, sizeof(key));
}


void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_SetPriorityGrouping(NVIC_PriorityGroup_3);
	
	NVIC_InitStructure.NVIC_IRQChannel = SENSOR_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM0_0_IRQn;
	NVIC_Init(&NVIC_InitStructure);
}

void SysTick_Configuration(void)
{
	SysTick_Config(12000000);
}

void UART_Configuration(void)
{
	UART_InitTypeDef UART_InitStructure;

	GPIO_PinRemapConfig(GPIOA, GPIO_Pin_0 | GPIO_Pin_1,GPIO_Remap_0);
	
	UART_InitStructure.UART_BaudRate = 115200;
	UART_InitStructure.UART_WordLength = UART_WordLength_8b;
	UART_InitStructure.UART_StopBits = UART_StopBits_1;
	UART_InitStructure.UART_Parity = UART_Parity_No;
	
	UART_Init(UART0, &UART_InitStructure);
}


void TIMER_Configuration(void)
{
	TIM_InitTypeDef TIMER_InitStruct;
	SYSCTRL_ClocksTypeDef clocks;
	
	SYSCTRL_GetClocksFreq(&clocks);
	TIMER_InitStruct.TIM_Period = clocks.PCLK_Frequency;
	TIMER_InitStruct.TIMx = TIM_0;
	
	TIM_Init(TIMM0, &TIMER_InitStruct);
	TIM_ITConfig(TIMM0, TIM_0, ENABLE);
	TIM_Cmd(TIMM0, TIM_0, DISABLE);
}




#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
	/* User can add his own implementation to report the file name and line number,
	 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

	/* Infinite loop */
	while (1)
	{
	}
}
#endif


